package userservice

import (
	"context"
	"gitee.com/go-mid/infra/xlog"
	"gitee.com/go-mid/infra/xtime"
	"gitee.com/go-mid/user/internal/component"
	"gitee.com/go-mid/user/internal/entity"
	"github.com/jinzhu/copier"
	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/status"
)

type UserAttrInfo struct {
	ID      int64            `json:"id" bdb:"id"`             //
	UserID  int64            `json:"user_id" bdb:"user_id"`   //用户id
	Ct      int64            `json:"ct" bdb:"ct"`             //创建时间
	Ut      int64            `json:"ut" bdb:"ut"`             //修改时间
	Attr    string           `json:"attr" bdb:"attr"`         //属性key
	Val     string           `json:"val" bdb:"val"`           //属性值
	AppID   int64            `json:"app_id" bdb:"app_id"`     //所属应用
	KeyType EnumUserAttrType `json:"key_type" bdb:"key_type"` //key类型

} //@name 用户表信息

func (m *UserServiceImpl) toUserAttrInfo(ctx context.Context, item *entity.UserAttr) *UserAttrInfo {
	if item == nil {
		return nil
	}
	var info UserAttrInfo
	copier.Copy(&info, item)
	return &info
}
func (m *UserServiceImpl) toUserAttrInfos(ctx context.Context, items []*entity.UserAttr) []*UserAttrInfo {
	var infos = make([]*UserAttrInfo, 0)
	for _, item := range items {
		infos = append(infos, m.toUserAttrInfo(ctx, item))
	}
	return infos
}

type ListUserAttrReq struct {
	Offset    int64 `json:"offset"`     // 下一页游标
	Limit     int64 `json:"limit"`      // 每页条数
	WithTotal bool  `json:"with_total"` // 是否查询总量
} //@name 查询用户表入参

type ListUserAttrRes struct {
	Items  []*UserAttrInfo `json:"items"`
	Offset int64           `json:"offset"`
	More   bool            `json:"more"`
	Total  int             `json:"total"`
} //@name 查询用户表响应

func (m *UserServiceImpl) ListUserAttr(ctx context.Context, req *ListUserAttrReq) (res *ListUserAttrRes, err error) {
	fun := "UserServiceImpl.ListUserAttr -->"
	st := xtime.NewTimeStat()
	defer func() {
		xlog.Infow(ctx, fun, "durationMs", st.Millisecond(), "req", req, "res", res, "err", err)
	}()
	var items []*entity.UserAttr
	var offset = req.Offset
	var limit = req.Limit
	if offset < 0 {
		offset = 0
	}
	if limit < 1 || limit > 1000 {
		limit = 1000
	}
	var where = map[string]interface{}{
		//	todo where条件
		"_limit":   []int64{offset, limit + 1},
		"_orderby": "ct desc",
	}
	err = component.XDBUser.Select(ctx, entity.UserAttrTable, where, &items)
	if err != nil {
		xlog.Warnf(ctx, "%s select err: req: %v, err: %v", fun, req, err)
		err = status.Error(codes.Internal, err.Error())
		return
	}
	var more bool
	if len(items) > int(limit) {
		items = items[0:limit]
		more = true
	}
	offset = offset + int64(len(items))
	var total int
	if req.WithTotal {
		delete(where, "_limit")
		delete(where, "_orderby")
		cnt, err := component.XDBUser.SelectCount(ctx, entity.UserAttrTable, where)
		if err != nil {
			xlog.Warnf(ctx, "%s count err: req: %v, err: %v", fun, req, err)
			err = status.Error(codes.Internal, err.Error())
			return nil, err
		}
		total = cnt
	}
	res = &ListUserAttrRes{
		Items:  m.toUserAttrInfos(ctx, items),
		Offset: offset,
		More:   more,
		Total:  total,
	}
	return
}
